package org.opens.javaskill.thread.api;

public class StopThread2 {

    public static void main(String[] args) {
        ThreadService threadService = new ThreadService();
        threadService.execute(() -> {
            while(true) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            }
        });
        threadService.shutdown(5000);
        System.out.println("结束了");
    }

}

/**
 * 说明:
 *      1. 这个方法的巧妙之处在于, 使用一个非后台线程去创建一个守护线程去执行传递进来的任务, 然后使这个线程join等待所创建的哪个线程, 然后该线程
 *      有三种结束方式:
 *          - 子线程执行结束, 修改了父线程的结束标记, 然后父线程使用标记法停止自己;
 *          - 查过所设置的等待时间, 如果超时, 就使main线程去打断executeThread, 然后executeThread被终止, 然后子后台线程也就自己结束了;
 */
class ThreadService {

    private Thread executeThread;

    private boolean finished = false;

    public void execute(Runnable task) {
        executeThread = new Thread() {

            @Override
            public void run() {
                Thread innerThread = new Thread(task);
                innerThread.setDaemon(true);

                innerThread.start();

                try {
                    innerThread.join();
                    finished = true;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        };

        executeThread.start();
    }

    public void shutdown(long mills) {
        long currentTime = System.currentTimeMillis();

        while (!finished) {
            if ( (System.currentTimeMillis() - currentTime) >= mills ) {
                System.out.println("任务超时, 需要终止~");
                executeThread.interrupt();
                break;
            }

            // 如果innerThread等待的task线程还在执行中, 且小于等待时间, 就休眠一下下.
            try {
                // 这个线程睡眠的是main线程
                Thread.sleep(10);
            } catch (InterruptedException e) {
                System.out.println("执行线程被打断");
                break;
            }
        }
    }

}
